package org.example;

import com.sun.jndi.url.corbaname.corbanameURLContextFactory;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.*;
import java.util.*;

class communication implements Serializable{
    int flag;
    String user;
    String message;

    communication(int i1, String s2,String s3){
        this.flag=i1;
        this.user=s2;
        this.message=s3;
    }

    @Override
    public String toString(){
        return "[flag]:"+flag+"   [user]:"+user+"    [message]:"+message;
    }
}

public class TCPServer {
    private ServerSocket serverSocket;
    static Map<String, ObjectOutputStream> allUser=new HashMap<String, ObjectOutputStream>();
    private int Port=8888;
    public static void main(String[] args) throws IOException {
        TCPServer tcpServer=new TCPServer();
        tcpServer.start();
    }

    /**
     * 启动服务器，监听客户端连接
     */
    public void start() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 创建ServerSocket对象，指定端口号
                    serverSocket = new ServerSocket(Port);
                    while (true) {
                        // 等待客户端连接，accept方法会阻塞程序执行，直到有客户端连接成功
                        Socket socket = serverSocket.accept();
                        System.out.println("用户连接");
                        // 创建一个新线程来处理客户端请求
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    // 处理客户端的请求
                                    request(socket);
                                } catch (IOException | ClassNotFoundException | SQLException e) {
                                    throw new RuntimeException(e);
                                }
                            }
                        }).start();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void request(Socket socket) throws IOException, ClassNotFoundException, SQLException {
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        String url = "jdbc:mysql://localhost:3306/chess";
        String user = "root";
        String password = "abc123";
        Connection connection = DriverManager.getConnection(url, user, password);
        String nowUser=null;
        String otherUser=null;
        ObjectOutputStream otherOOS = null;
        while(true){
            communication content=(communication) ois.readObject();
            if(content.flag==Const.login){
                nowUser=content.user;
                allUser.put(nowUser,oos);
            }
            if(content.flag==Const.logout && nowUser!=null){
                allUser.remove(nowUser);

                String sql = "delete from room where user = ?";
                PreparedStatement preparedStatement= connection.prepareStatement(sql);
                preparedStatement.setString(1, nowUser);
                preparedStatement.execute();

                socket.close();
                break;
            }
            if(content.flag==Const.searching){
                // 处理用户搜索对手的请求
                // 将用户添加到等待队列或匹配对手
                String sql = "INSERT INTO `room` (user) VALUES (?)";
                PreparedStatement preparedStatement= connection.prepareStatement(sql);
                preparedStatement.setString(1, nowUser);
                preparedStatement.execute();
            }
            if(content.flag==Const.ask){
                // 处理用户发起对战请求的情况
                // 向被请求用户发送请求信息
                otherUser=content.user;
                otherOOS=allUser.get(otherUser);

                String sql="select * from room where user = ?";
                PreparedStatement Pstatement=connection.prepareStatement(sql);
                Pstatement.setString(1, otherUser);
                ResultSet rset=Pstatement.executeQuery();
                if(rset.next()) otherOOS.writeObject(new communication(Const.ask,nowUser,null));
                else otherOOS.writeObject(new communication(Const.response,nowUser,"no"));
            }
            if(content.flag==Const.response){
                // 处理用户对对战请求的回应
                // 根据回应信息确定对战是否开始
                otherUser=content.user;
                otherOOS=allUser.get(otherUser);

                if(content.message.equals("ok")){
                    otherOOS.writeObject(new communication(Const.response,nowUser,"ok"));
                }else{
                    otherOOS.writeObject(new communication(Const.response,nowUser,"no"));
                }
            }
            if(content.flag==Const.matched){
                // 处理两个用户匹配成功的情况
                // 进行游戏初始化并通知双方
                String sql = "delete from room where user = ?";
                PreparedStatement preparedStatement= connection.prepareStatement(sql);
                preparedStatement.setString(1, nowUser);
                preparedStatement.execute();

                sql = "delete from room where user = ?";
                PreparedStatement preparedStatement2= connection.prepareStatement(sql);
                preparedStatement2.setString(1, otherUser);
                preparedStatement2.execute();

                sql = "select num from user where username = ?";
                PreparedStatement preparedStatement3= connection.prepareStatement(sql);
                preparedStatement3.setString(1, nowUser);
                ResultSet Rset=preparedStatement3.executeQuery();
                Rset.next();
                int num1=Rset.getInt(1)+1;
                sql="update user set num = ? where username = ?";
                PreparedStatement preparedStatement4= connection.prepareStatement(sql);
                preparedStatement4.setInt(1,num1);
                preparedStatement4.setString(2, nowUser);
                preparedStatement4.execute();

                sql = "select num from user where username = ?";
                PreparedStatement preparedStatement5= connection.prepareStatement(sql);
                preparedStatement5.setString(1, otherUser);
                ResultSet Rset2=preparedStatement5.executeQuery();
                Rset2.next();
                int num2=Rset2.getInt(1)+1;
                sql="update user set num = ? where username = ?";
                PreparedStatement preparedStatement6= connection.prepareStatement(sql);
                preparedStatement6.setInt(1,num2);
                preparedStatement6.setString(2, otherUser);
                preparedStatement6.execute();


                oos.writeObject(new communication(Const.matched,otherUser,"white"));
                otherOOS.writeObject(new communication(Const.matched,otherUser,"black"));
            }
            if(content.flag==Const.send){
                // 处理用户发送聊天消息的情况
                // 将消息转发给对手
                otherOOS.writeObject(new communication(Const.send,otherUser, content.message));
            }
            if(content.flag==Const.play){
                // 处理用户发送落子信息的情况
                // 将落子信息转发给对手
                otherOOS.writeObject(new communication(Const.play,otherUser, content.message));
            }
            if(content.flag==Const.restart){
                // 处理用户请求重新开始游戏的情况
                // 发送重新开始游戏的请求给对手
                otherOOS.writeObject(new communication(Const.restart,otherUser, content.message));
            }
            if(content.flag==Const.end){
                // 处理游戏结束的情况
                // 关闭连接并清理相关资源
                if(content.message.equals("exit")){//一方退出
                    String sql = "delete from room where user = ?";
                    PreparedStatement preparedStatement= connection.prepareStatement(sql);
                    preparedStatement.setString(1,  content.user);
                    preparedStatement.execute();
                    otherOOS.writeObject(new communication(Const.end,otherUser, content.message));
                    otherOOS=null;
                    otherUser=null;
                }else if(content.message.equals("create")){//一方退出，另一方创建新房间
                    String sql = "INSERT INTO `room` (user) VALUES (?)";
                    PreparedStatement preparedStatement= connection.prepareStatement(sql);
                    preparedStatement.setString(1, content.user);
                    preparedStatement.execute();
                    otherOOS=null;
                    otherUser=null;
                }
                else{//一方达成胜利条件
                    int win=Integer.parseInt(content.message);

                    String sql = "select victory from user where username = ?";
                    PreparedStatement preparedStatement= connection.prepareStatement(sql);
                    preparedStatement.setString(1, otherUser);
                    ResultSet Rset=preparedStatement.executeQuery();
                    Rset.next();
                    int num=Rset.getInt(1)+1;
                    sql="update user set victory = ? where username = ?";
                    PreparedStatement preparedStatement2= connection.prepareStatement(sql);
                    preparedStatement2.setInt(1,num);
                    if(win==1){
                        preparedStatement2.setString(2, nowUser);
                    }else{
                        preparedStatement2.setString(2, otherUser);
                    }
                    preparedStatement2.execute();

                    win*=-1;
                    otherOOS.writeObject(new communication(Const.end,otherUser, ""+win));
                }
            }
            if(content.flag==Const.regret){
                otherOOS.writeObject(new communication(Const.regret, content.user, content.message));
            }
        }
    }
}